export function createStore(reducer, enhancer) {
    if (enhancer) {
        return enhancer(createStore)(reducer)
    }

    let state = reducer(undefined, { type: '@@REDUX_INIT' });
    let listeners = [];

    function getState() {
        return state
    }

    function subscribe(listener) {
        listeners.push(listener)
        // 销毁时只注销本身
        return () => {
            listeners = listeners.filter(l => l !== listener)
        }
    }

    function dispatch(action) {
        state = reducer(state, action)
        listeners.forEach(listener => listener())
    }

    return {
        getState,
        dispatch,
        subscribe,
    }
}

export function applyMiddleware(...middlewares) {
    // return 一个reducer？
    return (createStore) => (reducer) => {
        // 创建原始 store
        const store = createStore(reducer);

        // 初始时的 dispatch
        let dispatch = store.dispatch;

        // 中间件需要的 API
        const middlewareAPI = {
            getState: store.getState,
            dispatch: (action) => dispatch(action)
        };

        // 给每个中间件传入 API
        const chain = middlewares.map(middleware => middleware(middlewareAPI));
        // 组合所有中间件，创建增强版的 dispatch
        dispatch = compose(...chain)(store.dispatch);
        return {
            ...store,
            // 相当于只重写了store的dispatch
            dispatch
        };
    };
}

function compose(...funcs) {
    if (funcs.length === 0) {
        return arg => arg;
    }

    if (funcs.length === 1) {
        return funcs[0];
    }

    return funcs.reduce((a, b) => (...args) => a(b(...args)));
}

// 处理异步 action 的中间件
export const promiseMiddleware = ({ dispatch }) => next => action => {
    console.log('promiseMiddleware 开始');
    if (action instanceof Promise) {
        return action.then(dispatch);
    }
    return next(action);
};

// 处理函数类型 action 的中间件
export const thunkMiddleware = ({ dispatch, getState }) => next => action => {
    console.log('thunkMiddleware 开始');
    if (typeof action === 'function') {
        return action(dispatch, getState);
    }
    return next(action);
};


export const loggerMiddleware = () => next => action => {
    console.log('loggerMiddleware 开始');
    const result = next(action);
    console.log('loggerMiddleware 结束');
    return result;
};
